#include "HufArc.h"

int extrFile (FILE * fileToWrite, fileHead * list,FILE * arc)
{
	char * buf = (char*) calloc (SIZE_T_8,sizeof(char));
	unsigned long long int num = 0;
	unsigned long long int sizeFileSz = 0;
	unsigned int huff_block_size = 0;
	int i = 0;
	int rc = 0;
	if (!buf)
		cl_exit (EXTR_FILE_,MEMORY_ERR,fileToWrite,arc,list,buf);
	fseek (arc,7,SEEK_SET);
	
	while ((rc = fread (buf,sizeof(char),NAME_LEN,arc)) == 1)
	{
		num = strToInt (buf,NAME_LEN);
		if (num > SIZE_T_8) buf = (char*) calloc (num,sizeof(char));
		if ((rc = fread (buf,sizeof(char),num,arc)) != num)
		{
			free (buf);
			fclose (arc);
			fclose (fileToWrite);
			cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
			return 0;
		}
		if ((num != list->sizeName) || (strncmp(buf,list->fileName,num)))
		{
			fseek(arc,SIZE_T_8,SEEK_CUR); //skip mtime
			if ((rc = fread (buf,sizeof(char),SIZE_T_1,arc)) != SIZE_T_1)
			{
				free (buf);
				fclose (arc);
				fclose (fileToWrite);
				cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
				return 0;
			}
			num = strToInt (buf,SIZE_T_1);
			if (num & LEN_8_B )
			{
				if ((rc = fread (buf,sizeof(char),SIZE_T_8,arc)) != SIZE_T_8)
				{
					fclose (arc);
					fclose (fileToWrite);
					free (buf);
					cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
					return 0;
				}
				sizeFileSz = strToInt (buf,SIZE_T_8);
			} else {
				if ((rc = fread (buf,sizeof(char),SIZE_T_4,arc)) != SIZE_T_4)
				{
					fclose (arc);
					fclose (fileToWrite);
					free (buf);
					cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
					return 0;
				}
				sizeFileSz = strToInt (buf,SIZE_T_4);
			}
			
			if (!(num & NO_HUFF))
			{
				if ((rc = fread (buf,sizeof(char),SIZE_T_2,arc)) != SIZE_T_2) //read huff-block size
				{
					fclose (arc);
					fclose (fileToWrite);
					free (buf);
					cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
					return 0;
				}
				huff_block_size = strToInt (buf,SIZE_T_2);
				if ((rc = fread (buf,sizeof(char),sizeFileSz,arc)) != sizeFileSz)
				{
					fclose (arc);
					fclose (fileToWrite);
					free (buf);
					cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
					return 0;
				}
				sizeFileSz = strToInt (buf,sizeFileSz);
				fseek (arc,huff_block_size,SEEK_CUR);
			}
			fseek (arc,sizeFileSz +4,SEEK_CUR);
		} else {
			fseek (arc,SIZE_T_8 + SIZE_T_1,SEEK_CUR); // skip mtime and huff_ubits
			if (list->huff_ubits & LEN_8_B)
			{
				fseek (arc,SIZE_T_8,SEEK_CUR);
			} else {
				fseek (arc,SIZE_T_4,SEEK_CUR);
			}
			if (list->huff_ubits & NO_HUFF)
			{
				sizeFileSz = list->fileSize;
				if ((rc = copy (arc,fileToWrite,sizeFileSz,NULL)) != 0)
				{
					cl_exit (EXTR_FILE_,COPY_ERR,fileToWrite,arc,list,buf);
				return 0;
				}
				fseek (arc,SIZE_T_4,SEEK_CUR);
				/*for (;;)
				{
					if ((sizeFileSz/(SIZE_BUF)) != 0)//Why does SIZE_BUF in brackets? See definition
					{
						rc = fread (buf,sizeof(char),SIZE_BUF,arc);
						if (rc != SIZE_BUF)
						{
							free (buf);
							fclose (arc);
							fclose (fileToWrite);
							longjmp (errorBuf,READ_ERR);
							return 0;
						}
						strWrite (fileToWrite,buf,SIZE_BUF,NULL);
						sizeFileSz -= SIZE_BUF;
					} else {
						if (sizeFileSz > 0)
						{
							rc = fread (buf,sizeof(char),sizeFileSz,arc);
							if (rc != sizeFileSz)
							{
								free (buf);
								fclose (arc);
								fclose (fileToWrite);
								longjmp (errorBuf,READ_ERR);
								return 0;
							}
						strWrite (fileToWrite,buf,sizeFileSz,NULL);
						break;
						} else {
							break;
						}
					}
				}*/
			} else {
				buf = (char *) calloc (list->huff_block,sizeof(char));
				if ((rc = fread (buf,sizeof(char),list->huff_block,arc)) != list->huff_block)
				{
					free(buf);
					fclose(arc);
					fclose(fileToWrite);
					cl_exit (EXTR_FILE_,READ_ERR,fileToWrite,arc,list,buf);
					return 0;
				}
				//function to create huff_tree
				//function to uncoding file
				//function to copy
			}
		}
	}
	return 0;
}